SoftWrap 6.1.1 Loader
By: Gabri3l / ARTeam
http://cracking.accessroot.com

Creating a Loader to Patch Softwrap Protection DLL

The Target:
Professor Franklins' Instant Photo Effects 2
http://www.swsoftware.com/photo_software_effects.aspx
The Tools:
PEID, Ollydbg 1.10, dUP 1.14
The Protection:
Softwrap 6.1.1

Other Information:
I created this tutorial specifically for this target. The target application is 80+ megs to download so I can understand if you cannot download it.
If you still want to follow along you can download XPSmoker 4.4: http://www.xp-smoker.com/xpsmoker.html
It uses the exact same version of softwrap. The DLL is loaded at a different offset so when patching your offsets will be different but the code will be exactly the same.

I tried to make this as general as possible for people who are unable to download the target. In theory the methods for defeating the protection and the method for creating a loader should apply to other programs packed with this version of Softwrap.

Best viewed in Firefox at 1280x1024

Intro:

All the tools you will need can be found online:
http://navig8.to/diablo2oo2
http://home.t-online.de/home/Ollydbg/
http://Peid.has.it

First thing we want to do is to run the target once. You will be presented with a box telling you that softwrap needs to initilaize itself before it can run the program. Press Next and let it run. When that is done go ahead and close the application. Now we have Softwrap initialized and we can move onto removing the limitations. Opening up the target application in PEID shows that it is packed with Softwrap protection. It does not give the exact version but by pressing the BUY button in the Softwrap nag screen we will see that it is protected with version 6.1.1.



Body:

Defeating Softwrap Protection:

1. Okay, load photon.exe in Ollydbg (Make sure you have run it once to get rid of the first softwrap initilization nag)
2. There are a lot of excepetions that the protection uses to detect debuggers. So check the following:
Ignore Memory Access Violations in Kernel32
INT 3
Single Step Breaks
Integer Divison by Zero
Also, in your custom exceptions add:
C000001D (ILLEGAL INSTRUCTION)

3. All the exceptions Added? Good, press RUN. Give it a sec and you will be presented with the softwrap nag. (If this is your first time running it will be a nag about initializing softwrap stuff, I already ran it once so I am not talking about that nag here.)
4. Okay go to Olly and Press the PAUSE button. Go to View->Call Stack. You should see this:

Call stack of main thread
Address Stack Procedure / arguments Called from Frame
0012F3F0 77D493F5 Includes ntdll.KiFastSystemCallRet USER32.77D493F3 0012F424
0012F3F4 77D6EA24 USER32.WaitMessage USER32.77D6EA1F 0012F424
0012F428 77D5688A USER32.77D6E895 USER32.77D56885 0012F424
0012F450 77D568CC USER32.77D567D4 USER32.77D568C7 0012F44C
0012F470 77D5892D USER32.DialogBoxIndirectParamAorW USER32.77D58928 0012F46C
0012F49C 00EA355F softwrap.00F35899 softwrap.00EA3559 0012F498
0012F4B4 00EA3876 softwrap.00EA353A softwrap.00EA3871
*THIS IS THE ONE THAT CREATES THE NAG*
0012F4D4
0012F4D8 00EA40C9 softwrap.00EA37EC softwrap.00EA40C4 0012F4D4
0012FE24 00E919B8 softwrap.00EA3A69 softwrap.00E919B3 0012FE20
0012FE58 00508B3B Includes softwrap.00E919B8 Photon.00508B39 0012FE54
0012FF9C 00506F25 ? Photon.00508A87 Photon.00506F20

5. Remember this is a stack so whats on the TOP was called the most recently. So look down the stack and we can see the softwrap functions that call the dialogbox nag.
6. You can double click on each of the lines to see what each function is. I'm going to save you some time.
0012F4B4 00EA3876 softwrap.00EA353A <-- This is the function that makes the dialog nag. And we can see to the right of it it that it was called by 000EA3871.
7. So right click and choose Go-To->Expression and type in 000EA3871 Press Okay
8. You should land here:

00EA3871 E8 C4FCFFFF CALL softwrap.00EA353A

9. Right-Click and Choose Analyze code. Scroll up a bit and you should now see that this call is chosen by a Select Case. I have added some comments to help you better understand what is happening. Well how did I know what each function does? I used the old tried and true method of Trial and Error. I know what each of the cases does because I tried each one. Restarted the program and tried the next case. You can do the same if you like. I just thought I would save you some time.

00EA3843 48 DEC EAX ; Switch (cases 1..4)
00EA3844 74 35 JE SHORT softwrap.00EA387B ; Jumps to the Softwrap Initilization box again.
00EA3846 48 DEC EAX
00EA3847 74 28 JE SHORT softwrap.00EA3871 ; Jumps to the Softwrap Nag
00EA3849 48 DEC EAX
00EA384A 74 1B JE SHORT softwrap.00EA3867 ; Jumps to Softwrap server error box
00EA384C 48 DEC EAX
00EA384D 0F85 A4010000 JNZ softwrap.00EA39F7 ; Jumps to terminate program.
00EA3853 C705 48A6ED00 01>MOV DWORD PTR DS:[EDA648],1 ; Case 4 of switch 00EA3843 *THIS IS THE ONE WE WANT. STARTS PROG WITH NO NAG AND NO TIME TRIAL*
00EA385D E8 35A1FFFF CALL softwrap.00E9D997
00EA3862 E9 90010000 JMP softwrap.00EA39F7
00EA3867 E8 46FFFFFF CALL softwrap.00EA37B2 ; Case 3 of switch 00EA3843
00EA386C E9 86010000 JMP softwrap.00EA39F7
00EA3871 E8 C4FCFFFF CALL softwrap.00EA353A ; Case 2 of switch 00EA3843
00EA3876 E9 7C010000 JMP softwrap.00EA39F7
00EA387B 56 PUSH ESI ; Case 1 of switch 00EA3843
00EA387C 6A 08 PUSH 8

10. So by looking at the cases we can see that we always want to call case 4. Now we cannot just edit this code because it is unpacked at runtime. Instead we are going to restart the progam and set a breakpoint on the beginning of the Switch.
11. This next part is a little confusing since we cannot set a normal breakpoint. Reason: The integrity checks. When a debugger sets a breakpoint it actually overwrites the instruction with the INT3 opcode. It then knows to stop execution everytime it hits an INT3. This is a problem here because overwriting any part of the code will cause the program to detect a debugger. So we are going to use a memory breakpoint. It makes program execution take longer but it doesn't overwrite any code.
12. Okay go ahead and restart Photon.exe in Olly. Now we want to set a memory breakpoint on 00EA3843. So Right-Click Go-To->Expression and type 00EA3843. Hmmm, we get an error saying there is no memory at that address. The reason is because the Softwrap DLL has not been loaded yet.
13. Select Debugging Options and choose the EVENTS Tab. Check Break On New Module.
14. Press Run and the Executable Modules window will open. You can see the Softwrap DLL highlighted in Red. Double Click it. You will end up inside the Softwrap DLL.
15. Right-Click Go-To->Expression and type 00EA3843. Press Okay, You will see this:

00EA3843 11DB ADC EBX,EBX

16. This is Okay because the DLL hasnt been unpacked yet. We still want to break here. Right-Click and choose Breakpoint->Memory, On Access. This will set a breakpoint everytime the program accesses this exact memory location
17. We are almost ready to run the program. Go to Debugging Options again and UNcheck Break on New Module. Press Run.
18. You will break here:

00F3499B 2B6E 14 SUB EBP,DWORD PTR DS:[ESI+14]

19. Go ahead and press Run again. The rest of the functions we will break on are all pretty much about unpacking the DLL so they will be writing to the address we set our breakpoint on.
20. Continue Pressing Run until you break on 00EA3843 which has now been changed to DEC EAX.
21. Okay we are now at our Select Case. If you look at EAX you can see that it equals 2. Referring back to the select case code we see that Case 2 jumps to the Softwrap Nag. So we want to change this. Change the Case 2 jump JE SHORT softwrap.00EA3871 to JE SHORT softwrap.00EA3853 so it jumps to case 4: MOV DWORD PTR DS:[EDA648],1.
22. So select JE SHORT softwrap.00EA3871 and Press the SPACEABAR to Assemble type in JE SHORT softwrap.00EA3853. Done? Good. Press RUN.... Hey! It loads with no nag. (Also works if the programs trial period has expired)

Creating a Loader:

1. Now we know defeating the protection involves changing JE SHORT softwrap.00EA3871 to JE SHORT softwrap.00EA3853 in the Softwrap DLL
2. However, we cannot do this at runtime because integrity checks take place that will detect any modifications. So we need to make a loader that will wait until the integrity checks are finished and then patch the code. We even have a program that can help us do that: dUP (Diablo2oo2's Universal Patcher)
3. Open up dUP and go to the Offset Patch tab. Click on the [...] to browse for the original file. Choose Photon.exe
4. Check the Virtual Address Mode (for Packed PE files) option in dUP because the file we want to patch is packed. We cannot patch it until it is loaded into memory.
5. Now we want to change the instructions JE SHORT softwrap.00EA3871 to JE SHORT softwrap.00EA3853. This was at offset 00EA3847 for me. Changing the code in Olly we saw this:

00EA3847 74 28 JE SHORT softwrap.00EA3871
**BECOMES**
00EA3847 74 0A JE SHORT softwrap.00EA3853

6. So the instruction located at 00EA3847 is 74 and that stays the same. Only the instruction at 00EA3848 changes from 28 to 0A.
7. So in the Add Bytes box in dUP type in 00EA3848 for your Offset and for the Original Byte type in 28. For the Patched Byte type in 0A. **Note your Offsets may differ from mine so use the offset that you see on your computer when you look at the jump to the softwrap NAG**
8. Now, press the ADD button.
9. Allright we are almost ready to create a loader. If you look at the bottom of dUP you can see there is an option "Wait for MemoryValue Before patch (for Loaders)". You can press the little question mark beside it. It tells us to look for a place in memory where a DWORD value is written AFTER the integrity checks are done. We can then make the loader wait for that DWORD value to be written and then it will patch the DLL.
10. So now time to look for somewhere a DWORD value is moved into memory.
11. Before we continue we need to take a moment to analyze the problem. We know where the DLL checks to see if our program is registered, so the integrity check has to occur somewhere before that. There is very little chance that the integrity check is performed right before the registration check. So we can probably find a place in the code just before the registration check is made where a DWORD value is moved into memory.
12. How are we going to find the functions before the registration check is made? Well, we already did! When we first ran the program and paused it at the NAG screen we looked at the Call Stack. This gave us a list of the calls that took place before the NAG was created. So lets look again at the Call Stack:

Call stack of main thread
Address Stack Procedure / arguments Called from Frame
0012F3F0 77D493F5 Includes ntdll.KiFastSystemCallRet USER32.77D493F3 0012F424
0012F3F4 77D6EA24 USER32.WaitMessage USER32.77D6EA1F 0012F424
0012F428 77D5688A USER32.77D6E895 USER32.77D56885 0012F424
0012F450 77D568CC USER32.77D567D4 USER32.77D568C7 0012F44C
0012F470 77D5892D USER32.DialogBoxIndirectParamAorW USER32.77D58928 0012F46C
0012F49C 00EA355F softwrap.00F35899 softwrap.00EA3559 **THIS IS AFTER THE NAG IS CHECKED WE CANNOT LOOK FOR A DWORD HERE**
0012F498
0012F4B4 00EA3876 softwrap.00EA353A softwrap.00EA3871 **THIS IS THE ONE THAT CREATES THE NAG**
0012F4D4
**SO IN ONE OF THE FUNCTIONS BELOW WE NEED TO FIND A PLACE WHERE A DWORD IS WRITTEN**
0012F4D8 00EA40C9 softwrap.00EA37EC softwrap.00EA40C4 0012F4D4
0012FE24 00E919B8 softwrap.00EA3A69 softwrap.00E919B3 0012FE20
0012FE58 00508B3B Includes softwrap.00E919B8 Photon.00508B39 0012FE54
0012FF9C 00506F25 ? Photon.00508A87 Photon.00506F20

13. You may be thinking. "What are we looking for when you are talking about a DWORD being written to memory?" Let me explain:
In assembly you can write to the memory of a program (I will actually cover this more in my next tutorial where we inline patch a UPX packed program)
To write to the memory of a program we use the MOV instruction. The MOV intruction does what it sounds like it does; It MOVES the value on the right into the address on the left. Example: MOV EAX, ECX <-This MOVes the value of ECX into EAX.
14. Now when writing to memory we use the MOV instruction followed by the type of data we are moving. Example: MOV BYTE PTR DS:[401000], FF <-This will MOV the BYTE FF into the memory address 401000. The DS in front of the 401000 just specifies the Data Segment. Each program in Windows memory has its own Data Segment to run in. We include it in front of the address so the program knows to write the information to address 401000 in THIS programs Data Segment (as opposed to firefox, or even explorer which would have disastrous results)
15. Okay we now know how the program can write a DWORD to memory. So what we will be looking for is MOV DWORD PTR DS:[XXXXXXX], XXX
16. So lets begin looking. Load Photon.exe in Olly. Make sure your exceptions are set as before (Do not check Break on New Module)
17. Press the Run button and let it run until the NAG screen comes up.
18. When the NAG is up go to Olly and press the pause button, Then choose VIEW->Call Stack
19. You can look through the different calls for the MOV DWORD PTR DS instructions. You may find a few, but if you restart and trace through the code you will see that most of them get zero's moved into them. And since they had zero's in them to begin with, dUP will look at that location in memory and patch immediately;
The program will then detect the patch and not load.
-I'm, again, going to save us some time-
20. Double-click on this line in the Call Stack:
0012FE58 00508B3B Includes softwrap.00E919B8 Photon.00508B39
**Why am i telling you exactly where to look? There is no rule saying that you need to look in this specific place, in fact if you find some other DWORD value to use that is excellent. A lot of reversing ends up being trial and error. I am using the first option out of many different tries that worked for me.**
21. After Double Clicking on that line, you will find yourself here in the code:

00E9192D >/$ 55 PUSH EBP
00E9192E |. 8BEC MOV EBP,ESP
00E91930 |. 83EC 10 SUB ESP,10
00E91933 |. 8B45 10 MOV EAX,DWORD PTR SS:[EBP+10]
00E91936 |. FF05 887DED00 INC DWORD PTR DS:[ED7D88]
00E9193C |. 833D 887DED00 >CMP DWORD PTR DS:[ED7D88],2
00E91943 |. 53 PUSH EBX
00E91944 |. 56 PUSH ESI
00E91945 |. 57 PUSH EDI
00E91946 |. A3 20A7ED00 MOV DWORD PTR DS:[EDA720],EAX
00E9194B |. 7C 56 JL SHORT softwrap.00E919A3
00E9194D |. E8 CF670200 CALL softwrap.00EB8121
00E91952 |. 8BF0 MOV ESI,EAX
00E91954 |. C1E6 10 SHL ESI,10
00E91957 |. E8 C5670200 CALL softwrap.00EB8121
00E9195C |. 6A 10 PUSH 10
00E9195E |. 03F0 ADD ESI,EAX
00E91960 |. 33DB XOR EBX,EBX
00E91962 |. 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10]
00E91965 |. 53 PUSH EBX
00E91966 |. 50 PUSH EAX
00E91967 |. 33FF XOR EDI,EDI
00E91969 |. E8 025C0200 CALL softwrap.00EB7570
00E9196E |. 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10]
00E91971 |. 50 PUSH EAX
00E91972 |. FF75 08 PUSH DWORD PTR SS:[EBP+8]
00E91975 |. 56 PUSH ESI
00E91976 |. E8 62FDFFFF CALL softwrap.00E916DD
00E9197B |. 83C4 18 ADD ESP,18
00E9197E |. 83F8 FF CMP EAX,-1
00E91981 |. 74 1C JE SHORT softwrap.00E9199F
00E91983 |. 6A 01 PUSH 1
00E91985 |. 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10]
00E91988 |. 50 PUSH EAX
00E91989 |. FF75 0C PUSH DWORD PTR SS:[EBP+C]
00E9198C |. E8 0DFFFFFF CALL softwrap.00E9189E
00E91991 |. 83C4 0C ADD ESP,0C
00E91994 |. 83F8 FF CMP EAX,-1
00E91997 |. 75 04 JNZ SHORT softwrap.00E9199D
00E91999 |. 0BF8 OR EDI,EAX
00E9199B |. EB 02 JMP SHORT softwrap.00E9199F
00E9199D |> 8BFE MOV EDI,ESI
00E9199F |> 8BC7 MOV EAX,EDI
00E919A1 |. EB 67 JMP SHORT softwrap.00E91A0A
00E919A3 |> 6A 01 PUSH 1
00E919A5 |. 68 4944EC00 PUSH softwrap.00EC4449
00E919AA |. 33DB XOR EBX,EBX
00E919AC |. 53 PUSH EBX
00E919AD |. FF35 8C7DED00 PUSH DWORD PTR DS:[ED7D8C] ; softwrap.00E90000
00E919B3 |. E8 B1200100 CALL softwrap.00EA3A69
*************
00E919B8 |. E8 64670200 CALL softwrap.00EB8121 ******YOU ARE HERE******
*************
00E919BD |. 8BF0 MOV ESI,EAX
00E919BF |. C1E6 10 SHL ESI,10
00E919C2 |. E8 5A670200 CALL softwrap.00EB8121
00E919C7 |. 6A 10 PUSH 10
00E919C9 |. 03F0 ADD ESI,EAX
00E919CB |. E8 055C0200 CALL softwrap.00EB75D5
00E919D0 |. 6A 10 PUSH 10
00E919D2 |. 8BF8 MOV EDI,EAX
00E919D4 |. 53 PUSH EBX
00E919D5 |. 57 PUSH EDI
00E919D6 |. E8 955B0200 CALL softwrap.00EB7570
00E919DB |. 57 PUSH EDI
00E919DC |. FF75 08 PUSH DWORD PTR SS:[EBP+8]
00E919DF |. 56 PUSH ESI
00E919E0 |. E8 F8FCFFFF CALL softwrap.00E916DD
00E919E5 |. 83C4 1C ADD ESP,1C
00E919E8 |. 83F8 FF CMP EAX,-1
00E919EB |. 74 14 JE SHORT softwrap.00E91A01
00E919ED |. 57 PUSH EDI
00E919EE |. FF75 0C PUSH DWORD PTR SS:[EBP+C]
00E919F1 |. E8 16FEFFFF CALL softwrap.00E9180C
00E919F6 |. 83CB FF OR EBX,FFFFFFFF
00E919F9 |. 3BC3 CMP EAX,EBX
00E919FB |. 59 POP ECX
00E919FC |. 59 POP ECX
00E919FD |. 74 02 JE SHORT softwrap.00E91A01
00E919FF |. 8BDE MOV EBX,ESI
00E91A01 |> 57 PUSH EDI
00E91A02 |. E8 C95B0200 CALL softwrap.00EB75D0
00E91A07 |. 59 POP ECX
00E91A08 |. 8BC3 MOV EAX,EBX
00E91A0A |> 5F POP EDI
00E91A0B |. 5E POP ESI
00E91A0C |. 5B POP EBX
00E91A0D |. C9 LEAVE
00E91A0E \. C3 RETN

22. Right-Click in Olly and choose Analysis->Analyze Code. Then scroll UP until you see in Olly all the code you see above.
21. "So What?" you say. "The only MOV PTR DWORD DS I see here just moves EAX." That is correct, but we aren't going to use that. Instead we are going to look at the instructions just above it.
22. Look at the line 00E91936:

00E91936 |. FF05 887DED00 INC DWORD PTR DS:[ED7D88]
00E9193C |. 833D 887DED00 >CMP DWORD PTR DS:[ED7D88],2

23. The INC instruction INCrements the value by 1. So INC INC DWORD PTR DS:[ED7D88] will add 1 to the DWORD value stored at code location ED7D88. Looking at the code we see that it INCrements ED7D88, then tests if it is two. So we can assume that ED7D88 started out as 00000000. Then becomes 00000001 after the INC instruction.
24. Go back to dUP and in the MemoryAddress box at the bottom type in 00ED7D88 and in the MemoryValue box type in 00000001
**Why all the zero's? Because it is a DWORD. I will cover this in tutorial #5 as well. Each '00' you see makes up a BYTE, two BYTE's make a WORD and 4 BYTE's make a DWORD. So there needs to be 8 characters in all**
25. All done? Good. Press the "Create Loader" button. Give your Loader a name and press Okay.
26. Now double click your new loader and... (If all went well) It Works! No more nag screen.
27. Go ahead and change your clock around and try the loader again. Still works! Excellent, you have just made a loader to defeat the Softwrap protection. Because the loader was based on the functions and the memory of the softwrap DLL it should be able to be applied to other programs protected with the same version and DLL as this one.

 

Conclusion:

I used this particular program purely as a demonstration for patching Softwrap. If you like the program and are going to use it please purchase it.

Thanks to the whole ARTeam:
[Nilrem] [JDog45] [Shub - Nigurrath] [MaDMAn_H3rCuL3s] [Ferrari] [Kruger] [Teerayoot] [R@dier] [ThunderPwr] [Eggi] [EJ12N] [Stickman 373] [Bone Enterprise] [KaGra]

Thanks to all the people who take time to write tutorials.
Thanks to all the people who continue to develop better tools.
Thanks to Diablo2oo2 for his excellent patcher
Thanks to Exetools and Woodmann for being a great place of learning.
Thanks also to The Codebreakers Journal, and the Anticrack forum.

If you have any suggestions, comments or corrections email me: Gabri3l2003[at]yahoo.com